package com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.repository;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.alibaba.fastjson.JSONObject;

import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.FlowInvalidParamException;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.exception.RemoteApiCallException;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.object.ObjectMetaLayoutQueryVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.object.ObjectMetaLayoutVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.object.ObjectMetaQueryVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.model.object.ObjectMetaVo;
import com.iwhalecloud.citybrain.flow.platform.manager.domain.repository.ObjectComponentRepository;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.model.ObjApiResponse;
import com.iwhalecloud.citybrain.flow.platform.manager.infrastructure.utils.RestTemplateWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * @author lich
 * @date 2021/11/11
 */
@Service
@Slf4j
public class ObjectComponentRepositoryImpl implements ObjectComponentRepository {

    private static final String OBJECT_COMPONENT_ROOT_URI = "/object-component/api";

    private static final String QUERY_META_API = "/object-metas";
    private static final String QUERY_META_LAYOUT_API = "/object-metalayouts";

    static class ObjMetaQueryResponse extends ObjApiResponse<ObjectMetaVo>{};
    static class ObjMetaLayoutQueryResponse extends ObjApiResponse<List<ObjectMetaLayoutVo>>{};

    @Value("${flow.object.url:http://plm-object-component-daily.ingress.dayu.work}")
    private String objectDomain;

    @Autowired
    private RestTemplateWrapper restWrapper;

    @Override
    public ObjectMetaVo queryObjectMeta(ObjectMetaQueryVo queryVo) {
        if (StringUtils.isBlank(queryVo.getCode())) {
            throw new FlowInvalidParamException("对象类型代码不能为空");
        }
        String requestUrl = getObjectApiFullUrl(QUERY_META_API);
        requestUrl = withPathVariable(requestUrl, queryVo.getCode());
        log.info("requesting object meta {} with param {}", requestUrl, JSONObject.toJSONString(queryVo, true));
        ObjMetaQueryResponse apiResponse = restWrapper.get(requestUrl, ObjMetaQueryResponse.class);
        log.info("response with: {}", JSONObject.toJSONString(apiResponse, true));
        if (apiResponse.getSuccess() == null || apiResponse.getSuccess() == false) {
            throw new RemoteApiCallException("查询对象类型API业务上返回失败: " + apiResponse.getErrorMessage());
        }
        return apiResponse.getData();
    }

    private String withPathVariable(String requestUrl, String val) {
        if (!requestUrl.endsWith("/")) {
            requestUrl += "/";
        }
        return requestUrl + val;
    }

    @Override
    public List<ObjectMetaLayoutVo> queryObjectMetaLayoutList(ObjectMetaLayoutQueryVo queryVo) {
        if (StringUtils.isBlank(queryVo.getMetaCode())) {
            throw new FlowInvalidParamException("对象类型代码不能为空");
        }
        if (queryVo.getMetaVersion() == null) {
            throw new FlowInvalidParamException("对象类型版本不能为空");
        }
        String requestUrl = getObjectApiFullUrl(QUERY_META_LAYOUT_API);
        log.info("requesting object meta layout {}, with param: {}",
            requestUrl, JSONObject.toJSONString(queryVo, true));
        Map<String, Object> param = new HashMap<>(2);
        param.put("metaCode", queryVo.getMetaCode());
        param.put("metaVersion", queryVo.getMetaVersion());
        ObjMetaLayoutQueryResponse apiResponse = restWrapper.get(requestUrl, ObjMetaLayoutQueryResponse.class, param);
        log.info("response with: {}", JSONObject.toJSONString(apiResponse, true));
        if (apiResponse.getSuccess() == null || apiResponse.getSuccess() == false) {
            throw new RemoteApiCallException("查询对象类型Layout API业务上返回失败: " + apiResponse.getErrorMessage());
        }
        return apiResponse.getData();
    }

    private String getObjectApiFullUrl(String apiPath) {
        return StringUtils.join(objectDomain, OBJECT_COMPONENT_ROOT_URI, apiPath);
    }
}
